programming4us
           
 
 
Programming

Microsoft ASP.NET 3.5 : AJAX-Enabled Web Services - Remote Calls via Page Methods

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
1/4/2012 11:40:22 AM
Web and WCF services are simple and effective ways of implementing a server API. When the ASP.NET AJAX runtime engine has generated the proxy class, you’re pretty much done and can start calling methods as if they were local to the client. Web and WCF services, though, are not free of issues. They require an extra layer of code and additional files or assembly references to be added to the project. Is this a big source of concern for you? If so, consider that you have an alternative—page methods.

Introducing Page Methods

Page methods are simply public, static methods exposed by the code-behind class of a given page and decorated with the WebMethod attribute. The runtime engine for page methods and AJAX-enabled Web services is nearly the same. Using page methods saves you from the burden of creating and publishing a service; at the same time, though, it binds you to having page-scoped methods that can’t be called from within a page different from the one where they are defined. We’ll return later to the pros and cons of page methods. For now, let’s just learn more about them.

Defining a Page Method

Public and static methods defined on a page’s code-behind class and flagged with the WebMethod attribute transform an ASP.NET AJAX page into a Web service. Here’s a sample page method:

public class TimeServicePage : System.Web.UI.Page
{
[WebMethod]
public static DateTime GetTime()
{
return DateTime.Now;
}
}

You can use any data type in the definition of page methods, including .NET Framework types as well as user-defined types. All types will be transparently JSON-serialized during each call.

Note

The page class where you define methods might be the direct code-behind class or, better yet, a parent class. In this way, in the parent class you can implement the contract of the public server API and keep it somewhat separated from the rest of event handlers and methods that are specific to the page life cycle and behavior. Because page methods are required to be static (shared in Microsoft Visual Basic .NET), you can’t use the syntax of interfaces to define the contract. You have to resort to abstract base classes.


Alternatively, you can define Web methods as inline code in the .aspx source file as follows (and if you use Visual Basic, just change the type attribute to text/VB):

<script type="text/C#" runat="server">
[WebMethod]
public static DateTime GetTime()
{
return DateTime.Now;
}
</script>

Note that page methods are specific to a given ASP.NET page. Only the host page can call its methods. Cross-page method calls are not supported. If they are critical for your scenario, I suggest that you move to using Web or WCF services.

Enabling Page Methods

When the code-behind class of an ASP.NET AJAX page contains WebMethod-decorated static methods, the runtime engine emits a JavaScript proxy class nearly identical to the class generated for a Web service. You use a global instance of this class to call server methods. The name of the class is hard-coded to PageMethods. We’ll return to the characteristics of the proxy class in a moment.

Note, however, that page methods are not enabled by default. In other words, the PageMethods proxy class that you use to place remote calls is not generated unless you set the EnablePageMethods property to true in the page’s script manager:

<asp:ScriptManager runat="server" ID="ScriptManager1" EnablePageMethods="true" />


For the successful execution of a page method, the ASP.NET AJAX application must have the ScriptModule HTTP module enabled in the web.config file:
<httpModules>
<add name="ScriptModule"
type="System.Web.Handlers.ScriptModule, System.Web.Extensions" />
</httpModules>

Among other things, the module intercepts the application event that follows the loading of the session state, executes the method, and then serves the response to the caller. Acquiring session state is the step that precedes the start of the page life cycle. For page method calls, therefore, there’s no page life cycle and child controls are not initialized and processed.

Why No Page Life Cycle?

In the early days of ASP.NET AJAX (when it was code-named Atlas), page methods were instance methods and required view state and form fields to be sent with every call. The sent view state was the last known good view state for the page—that is, the view state downloaded to the client. It was common for developers to expect that during the page method execution, say, a TextBox was set to the same text just typed before triggering the remote call. Because the sent view state was the last known good view state, that expectation was just impossible to meet. At the same time, a large share of developers was also complaining that the view state was being sent at all during page method calls. View state is rarely small, which serves to increase the bandwidth and processing requirements for handling page methods.

In the end, ASP.NET AJAX extensions require static methods and execute them just before starting the page life cycle. The page request is processed as usual until the session state is retrieved. After that, instead of the page method call going through the page life cycle, the HTTP module kicks in, executes the method via reflection, and returns.

Coded in this way, the execution of a remote page method is quite effective and nearly identical to having a local Web service up and running. The fact that static methods are used and no page life cycle is ever started means one thing to you—you can’t programmatically access page controls and their properties.

Consuming Page Methods

The collection of page methods is exposed to the JavaScript code as a class with a fixed name—PageMethods. The schema of this class is similar to the schema of proxy classes for AJAX-enabled Web services. The class lists static methods and doesn’t require any instantiation on your own. Let’s take a look at the PageMethods class.

The Proxy Class

Unlike the proxy class for Web services, the PageMethods proxy class is always generated as inline script in the body of the page it refers to. That’s a fairly obvious choice given the fixed naming convention in use; otherwise, the name of the class should be different for each page. Here’s the source code of the PageMethods class for a page with just one Web method, named GetTime:

<script type="text/javascript">
var PageMethods = function()
{
PageMethods.initializeBase(this);
this._timeout = 0;
this._userContext = null;
this._succeeded = null;
this._failed = null;
}
PageMethods.prototype =
{
GetTime:function(succeededCallback, failedCallback, userContext)
{
return this._invoke(PageMethods.get_path(),
'GetTime', false, {}, succeededCallback,
failedCallback, userContext);
}
}
PageMethods.registerClass('PageMethods', Sys.Net.WebServiceProxy);
PageMethods._staticInstance = new PageMethods();

PageMethods.set_path = function(value) {
var e = Function._validateParams(arguments,
[{name: 'path', type: String}]);
if (e) throw e;
PageMethods._staticInstance._path = value;
}
PageMethods.get_path = function() {
return PageMethods._staticInstance._path;
}
PageMethods.set_timeout = function(value) {
var e = Function._validateParams(arguments,
[{name: 'timeout', type: Number}]);
if (e) throw e;
if (value < 0)
throw Error.argumentOutOfRange('value', value,
Sys.Res.invalidTimeout);
PageMethods._staticInstance._timeout = value;
}
PageMethods.get_timeout = function() {
return PageMethods._staticInstance._timeout;
}
PageMethods.set_defaultUserContext = function(value) {
PageMethods._staticInstance._userContext = value;
}
PageMethods.get_defaultUserContext = function() {
return PageMethods._staticInstance._userContext;
}
PageMethods.set_defaultSucceededCallback = function(value) {
var e = Function._validateParams(arguments,
[{name: 'defaultSucceededCallback', type: Function}]);
if (e) throw e;
PageMethods._staticInstance._succeeded = value;
}
PageMethods.get_defaultSucceededCallback = function() {
return PageMethods._staticInstance._succeeded;
}
PageMethods.set_defaultFailedCallback = function(value) {
var e = Function._validateParams(arguments,
[{name: 'defaultFailedCallback', type: Function}]);
if (e) throw e;
PageMethods._staticInstance._failed = value;
}
PageMethods.get_defaultFailedCallback = function() {
return PageMethods._staticInstance._failed;
}

PageMethods.set_path("/Core35/Ch20/CallPageMethod.aspx");
PageMethods.GetTime = function(onSuccess,onFailed,userContext) {
PageMethods._staticInstance.GetTime(onSuccess,onFailed,userContext);
}
</script>


As you can see, the structure of the class is nearly identical to the proxy class of an AJAX Web service. You can define default callbacks for success and failure, user context data, path, and timeout. A singleton instance of the PageMethods class is created, and all callable methods are invoked through this static instance. No instantiation whatsoever is required.
Executing Page Methods

The PageMethods proxy class has as many methods as there are Web methods in the code-behind class of the page. In the proxy class, each mapping method takes the same additional parameters you would find with a Web service method: completed callback, failed callback, and user context data. The completed callback is necessary to update the page with the results of the call. The other parameters are optional. The following code snippet shows a locally-defined getTime function bound to a client event handler. The function calls a page method and leaves the methodCompleted callback the burden of updating the user interface as appropriate.

function getTime()
{
PageMethods.GetTime(methodCompleted);
}
function methodCompleted(results, context, methodName)
{
// Format the date-time object to a more readable string
var displayString = results.format("ddd, dd MMMM yyyy");
$get("Label1").innerHTML = displayString;
}

The signature of a page method callback is exactly the same as the signature of an AJAX Web service proxy.

Timeout, error handling, and user feedback are all aspects of page methods that require the same programming techniques discussed earlier for Web service calls.

Note

From page methods, you can access session state, the ASP.NET Cache, and User objects, as well as any other intrinsic objects. You can do that using the Current property on HttpContext. The HTTP context is not specific to the page life cycle and is, instead, a piece of information that accompanies the request from the start.


Page Methods vs. AJAX-Enabled Services

From a programming standpoint, no difference exists between service methods and page methods. Performance is nearly identical. A minor difference is the fact that page methods are always emitted as inline JavaScript, whereas this aspect is configurable for services.

Web services are publicly exposed over the Web and, as such, they’re publicly callable by SOAP-based clients (unless the protocol is disabled). A method exposed through a Web or WCF service is visible from multiple pages; a page method, conversely, is scoped to the page that defines it. On the other hand, a set of page methods saves you from the additional work of developing a service.

Whatever choice you make, it is extremely important that you don’t call any critical business logic from page and service methods. Both calls can be easily replayed by attackers and have no additional barrier against one-click and replay attacks. Normally, the view state, when spiced up with user key values, limits the range of replay attacks. As mentioned, though, there’s no view state involved with page and Web service method calls, so even this small amount of protection isn’t available for these specific cases. However, if you limit your code to calling UI-level business logic from the client, you should be fine.

Note

I repeatedly mentioned that AJAX-enabled services, including Web services, are to be considered local to the application. They are in fact application services implemented as ASP.NET Web services because of the lack of alternatives. With ASP.NET 3.5, though, you have the possibility of using WCF services. What if you want to incorporate data coming from a classic WS-* Web service? You can’t invoke the Web service directly from the client, but nothing prevents you from making a server-to-server call using the networking API of the .NET Framework.

Other -----------------
- Microsoft ASP.NET 3.5 : WCF Services for ASP.NET AJAX Applications
- Mobile Game Networking Essentials : Network Programming and J2ME
- Mobile Game Networking Essentials : Multiplayer Game Basics & Network Game Problems and Solutions
- Software Testing with Visual Studio Team System 2008 : Debug and running web test (part 2) - Running the test
- Software Testing with Visual Studio Team System 2008 : Debug and running web test (part 1) - Settings for .testrunconfig file
- Visual Studio Team System 2008 : Web test editor (part 3) - Toolbar properties
- Visual Studio Team System 2008 : Web test editor (part 2) - Other request properties
- Visual Studio Team System 2008 : Web test editor (part 1) - Web test properties & Web test request properties
- Build Mobile Websites and Apps for Smart Devices : Design for Mobile - Standing on the Shoulders of Giants
- Build Mobile Websites and Apps for Smart Devices : Design for Mobile - Build a Better Mouse
- Developing BlackBerry Tablet Applications with Flex 4.5 : Create a Flex Mobile Project (part 4) - Reading and setting author information for debug
- Developing BlackBerry Tablet Applications with Flex 4.5 : Create a Flex Mobile Project (part 3) - Setup Device
- Developing BlackBerry Tablet Applications with Flex 4.5 : Create a Flex Mobile Project (part 2) - Setup Simulator
- Developing BlackBerry Tablet Applications with Flex 4.5 : Create a Flex Mobile Project (part 1)
- Programming Excel with VBA and .NET : Procedures - Properties & Events
- Programming Excel with VBA and .NET : Procedures - Arguments and Results
- LINQ to Objects : Writing Basic Queries - How to Filter the Results (Where Clause)
- LINQ to Objects : Writing Basic Queries - Query Syntax Style Options
- DirectX 10 Game Programming : The 2D Resurgence - Sprites
- DirectX 10 Game Programming : The 2D Resurgence - Textures
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us